package com.rockcent.api;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.common.common.JsonResult;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.RequestUtils;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.PlatformMark;
import com.rockcent.mall.lib.repository.MallRepository;
import com.rockcent.mall.lib.repository.UserAdminRepository;
import com.rockcent.mall.lib.repository.UserMallRepository;
import com.rockcent.mall.lib.repository.UserMerchantRepository;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by hone on 17-3-13.
 */
public class AuthUserInterceptor extends HandlerInterceptorAdapter {

    private final Logger log = LoggerFactory.getLogger(AuthUserInterceptor.class);

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private String userToken;

    @Autowired
    private UserAdminRepository userAdminRepository;

    @Autowired
    private UserMallRepository userMallRepository;

    @Autowired
    private UserMerchantRepository userMerchantRepository;

    @Autowired
    private MallRepository mallRepository;

    @Autowired
    private ObjectMapper objectMapper;

    public AuthUserInterceptor(String userToken) {
        this.userToken = userToken;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getRequestURI();
        String userToken = request.getHeader(this.userToken);
        if (StringUtils.isBlank(userToken)) {
            userToken = RequestUtils.getStringParameter(request, this.userToken);
        }
        log.info("======================>userToken : {}", userToken);
        if (StringUtils.isBlank(userToken)) {
            response.getWriter().print(JSON.toJSONString(new JsonResult<>("10001", "user_token 不能为空")));
            response.getWriter().close();
            return false;
        }
        String userInfoId = stringRedisTemplate.boundValueOps(UserInfo.REDIS_USER_TOKEN_PREFIX + userToken).get();
        if (StringUtils.isBlank(userInfoId)) {
            response.getWriter().print(JSON.toJSONString(new JsonResult<>("10003", "user_token 无效")));
            response.getWriter().close();
            return false;
        }
        String platformMark = request.getHeader("platformMark");
        if (StringUtils.isEmpty(platformMark)) {
            platformMark = RequestUtils.getStringParameter(request, "platformMark");
        }
        if (StringUtils.isEmpty(platformMark)) {
            response.getWriter().print(JSON.toJSONString(new JsonResult<>("10001", "platformMark 不能为空")));
            response.getWriter().close();
            return false;
        }
        if (!EnumUtils.isValidEnum(PlatformMark.class, platformMark)) {
            response.getWriter().print(JSON.toJSONString(new JsonResult<>("10001", "platformMark 无效")));
            response.getWriter().close();
            return false;
        }
        if (platformMark.equals(PlatformMark.ADMIN.toString())) {
            UserAdmin userAdmin = userAdminRepository.findByUserId(new Long(userInfoId));
            if (userAdmin == null || userAdmin.getIsSuperAdmin() == null) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "没权限")));
                response.getWriter().close();
                return false;
            }
            if (userAdmin.getAvailable() == null || userAdmin.getAvailable() != Whether.YES) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "没权限")));
                response.getWriter().close();
                return false;
            }
            //验证用户请求是否有权限,除了超级管理员
            if (userAdmin.getIsSuperAdmin() != null && userAdmin.getIsSuperAdmin() != Whether.YES) {
                String reqUri = request.getRequestURI();
                int index = reqUri.indexOf(Routes.API_VERSION);
                if (index == 0) {
                    reqUri = reqUri.replace(Routes.API_VERSION, "");
                    String backendUrl = stringRedisTemplate.boundValueOps(userInfoId + "-" + reqUri).get();
                    if (StringUtils.isEmpty(backendUrl)) {
                        response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "没权限")));
                        response.getWriter().close();
                        return false;
                    }
                }
            }
        } else if (platformMark.equals(PlatformMark.MALL.toString())) {
            String domain = request.getHeader("domain");
            if (StringUtils.isBlank(domain)) {
                domain = RequestUtils.getStringParameter(request, "domain");
            }
            if (StringUtils.isBlank(domain)) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "domain不能为空")));
                response.getWriter().close();
                return false;
            }
            Mall mall = mallRepository.findByHostnameOrCustomerPlatformDomain(domain);
            if (mall == null) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "domain不存在")));
                response.getWriter().close();
                return false;
            }
            UserMall userMall = userMallRepository.findByMallIdAndUserId(mall.getId(), new Long(userInfoId));
            if (userMall == null) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "用户没有M端权限")));
                response.getWriter().close();
                return false;
            }
            if (userMall.getAvailable() == null || userMall.getAvailable() != Whether.YES) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "用户未启用")));
                response.getWriter().close();
                return false;
            }
            //验证用户请求是否有权限,除了超级管理员
            if (userMall.getIsSuperAdmin() != null && userMall.getIsSuperAdmin() != Whether.YES) {
                String reqUri = request.getRequestURI();
                int index = reqUri.indexOf(Routes.API_VERSION);
                if (index == 0) {
                    reqUri = reqUri.replace(Routes.API_VERSION, "");
                    String backendUrl = stringRedisTemplate.boundValueOps(userToken + "-" + userMall.getMallId() + "-" + reqUri).get();
                    if (StringUtils.isEmpty(backendUrl)) {
                        response.getWriter().print(objectMapper.writeValueAsString(new JsonResult<>("CD10105", "没平台权限")));
                        response.getWriter().close();
                        return false;
                    }
                }
            }
        } else if (platformMark.equals(PlatformMark.MERCHANT.toString())) {
            String domain = request.getHeader("domain");
            if (StringUtils.isBlank(domain)) {
                domain = RequestUtils.getStringParameter(request, "domain");
            }
            if (StringUtils.isBlank(domain)) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "domain不能为空")));
                response.getWriter().close();
                return false;
            }
            Mall mall = mallRepository.findByHostnameOrCustomerPlatformDomain(domain);
            if (mall == null) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "domain不存在")));
                response.getWriter().close();
                return false;
            }
            String mId = stringRedisTemplate.boundValueOps(UserInfo.REDIS_MERCHANT_LOGIN_PREFIX + userToken + "_" + domain).get();
            if (StringUtils.isEmpty(mId)) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "用户没有B端权限")));
                response.getWriter().close();
                return false;
            }
            UserMerchant userMerchant = userMerchantRepository.findByUserIdAndMallIdAndMerchantId(new Long(userInfoId), mall.getId(), new Long(mId));
            if (userMerchant == null) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "用户没有B端权限")));
                response.getWriter().close();
                return false;
            }
            if (userMerchant.getAvailable() == null || userMerchant.getAvailable() != Whether.YES) {
                response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "用户未启用")));
                response.getWriter().close();
                return false;
            }
            //验证用户请求是否有权限,除了超级管理员
            if (userMerchant.getIsSuperAdmin() != null && userMerchant.getIsSuperAdmin() != Whether.YES) {
                String reqUri = request.getRequestURI();
                int index = reqUri.indexOf(Routes.API_VERSION);
                if (index == 0) {
                    reqUri = reqUri.replace(Routes.API_VERSION, "");
                    log.info("======================>userToken:{},mallId:{},merchantId:{},reqUri:{}", userToken, userMerchant.getMallId(), userMerchant.getMerchantId(), reqUri);
                    String backendUrl = stringRedisTemplate.boundValueOps(userToken + "-" + userMerchant.getMallId() + "-" + userMerchant.getMerchantId() + "-" + reqUri).get();
                    if (StringUtils.isEmpty(backendUrl)) {
                        response.getWriter().print(objectMapper.writeValueAsString(new JsonResult<>("CD10105", "没平台权限")));
                        response.getWriter().close();
                        return false;
                    }
                }
            }
        } else {
            response.getWriter().print(JSON.toJSONString(new JsonResult<>("10101", "没权限")));
            response.getWriter().close();
            return false;
        }
        return super.preHandle(request, response, handler);
    }
}
